;----------------------------------------------------------------------
;
; Copyright 2009-2010 IAR Systems AB.
;
; $Revision: 959 $
;
;----------------------------------------------------------------------
;
; Created:        2009 ILAK
; Revised:
;
; Entries:        ?C_STARTUP      start address (in reset vector)
;
;----------------------------------------------------------------------

        MODULE  CSTARTUP
        extern  _main
        extern  _memcpy
        extern  _memset
        extern  _exit
        extern  ___iar_data_init2
        extern  ___call_ctors
        extern  ___low_level_init
        //extern  _vector_table
        //extern  _OSTickISR
        //extern  _OSCtxSw
        public  __iar_cstart_call_ctors
        public  __INIT_CTORS  
        public  __INIT_TBR 
        public  ?C_STARTUP
        public  __iar_program_start



;----------------------------------------------------------------------
;
; CSTACK - The stack segment
;
; Set the stack size in the linker command file (.xcl), not here!
;
;----------------------------------------------------------------------

        section  CSTACK:DATA:NOROOT(2)
        SECTION .tbr_table:CODE:NOROOT(2)
        section .inttable:CODE:ROOT(2)
        
        
;----------------------------------------------------------------------
;
; ?C_STARTUP (for SH-2A/SH2A-FPU)
;
;----------------------------------------------------------------------
;----------------------------------------------------------------------
; define reset vector and initial stack pointer
;----------------------------------------------------------------------
        section  .intvec:CODE:ROOT(2)

        DATA
intvec:
        dc32   ?C_STARTUP
        dc32   sfe(CSTACK)
        dc32   ?C_STARTUP
        dc32   sfe(CSTACK)
        CODE

        SECTION __DEFAULT_CODE_SECTION__:CODE:ROOT(2)
        CODE
?C_STARTUP:
__iar_program_start:
        //REQUIRE _vector_table
        REQUIRE c_init
        mov.l   __ct_intvec,r0
        ldc     r0,vbr                  ; init VBR to start of vector table
#if __CORE__ == __SH2AFPU__
        ; Set floating point rounding mode to nearest
        mov.l   __ct_floatmode,r0
        lds     r0, fpscr
#endif

        SECTION __DEFAULT_CODE_SECTION__:CODE:NOROOT(2)
        CODE
__INIT_TBR:
        mov.l   __ct_tbr,r0
        ldc     r0, TBR

        SECTION __DEFAULT_CODE_SECTION__:CODE:ROOT(2)
        CODE
c_init:
;----------------------------------------------------------------------
;
; Perform C initialization.
;
;----------------------------------------------------------------------

;----------------------------------------------------------------------
; Call __low_level_init to perform initialization before initializing
; segments and calling main. If the function returns 0 no segment
; initialization should take place.
;
; Link with your own version of __low_level_init to override the
; default action: to do nothing but return 1.
;----------------------------------------------------------------------
        mov.l   __ct__low_level_init, r0
        jsr     @r0    
        nop

        tst     r0,r0
        bt      skip_init

;----------------------------------------------------------------------
; Segment initialization:
;----------------------------------------------------------------------

        mov.l   __ct__iar_data_init2, r0
        jsr     @r0
        nop

;----------------------------------------------------------------------
; Init C++ objects
;----------------------------------------------------------------------

        SECTION __DEFAULT_CODE_SECTION__:CODE:NOROOT(2)
        CODE
__INIT_CTORS:
__iar_cstart_call_ctors:
        mov.l   __ct_PREINIT_ARRAY, r4
        mov.l   __ct__call_ctors, r0
        mov.l   __ct_INIT_ARRAY, r5
        jsr     @r0    
        nop
        nop        

;----------------------------------------------------------------------
; Call main() with no arguments
;----------------------------------------------------------------------

        SECTION __DEFAULT_CODE_SECTION__:CODE:ROOT(2)
        CODE
skip_init:
        mov.l   __ct_main, r0
        jsr     @r0    
        nop                                     ; (delay slot)

;----------------------------------------------------------------------
; Now when we are ready with our C program we must perform a system-
; dependent action. In this simple case we jump to exit
;----------------------------------------------------------------------
        mov     r0,r4
        mov.l   __ct_exit, r0
        jsr     @r0    
        nop                                  ; (delay slot)
        nop

        SECTION __DEFAULT_CODE_SECTION__:CODE:NOROOT(2)
        public ?DL_1_L00
        DATA
?DL_1_L00:
__ct_intvec:
        dc32   sfb(.inttable) - 0x10
__ct__low_level_init:
        dc32   ___low_level_init
__ct__iar_data_init2:
        dc32   ___iar_data_init2
__ct_main: 
        dc32  _main
__ct_exit:
        dc32  _exit
__ct_sfb_stack:
        dc32  sfb(CSTACK)
__ct_sfs_stack:
        dc32  sizeof(CSTACK)
#if __CORE__ == __SH2AFPU__
__ct_floatmode:
        dc32  0x00040000
#endif
        SECTION __DEFAULT_CODE_SECTION__:CODE:NOROOT(2)
__ct_tbr:
        dc32  sfb(.tbr_table)
        CODE


        SECTION __DEFAULT_CODE_SECTION__:CODE:NOROOT(2)

        EXTERN  SHT$$PREINIT_ARRAY$$Base
        DATA
__ct_PREINIT_ARRAY:
        DATA
        DC32    SHT$$PREINIT_ARRAY$$Base
__ct__call_ctors:
        dc32  ___call_ctors
        EXTERN  SHT$$INIT_ARRAY$$Limit
__ct_INIT_ARRAY:
        DC32    SHT$$INIT_ARRAY$$Limit
        CODE

        end
